#!/usr/bin/env python
import redis
import json
import time
import uuid
import base64
from tasks import app

# Redis连接配置
REDIS_URL = 'redis://:Hewenyu1994@121.5.249.100:6379/0'
redis_client = redis.from_url(REDIS_URL)

def clear_redis_celery_keys():
    """清除Redis中的所有Celery相关键"""
    print("正在清除Redis中的Celery键...")
    for key in redis_client.keys('celery*'):
        redis_client.delete(key)
    print("已清除所有Celery键")

def send_python_task():
    """使用Python Celery发送任务"""
    task_id = str(uuid.uuid4())
    result = app.send_task(
        'tasks.add',
        args=[10, 20],
        task_id=task_id
    )
    print(f"Python任务已发送，ID: {result.id}")
    return result.id

def capture_message_format():
    """捕获Redis中的消息格式"""
    # 获取celery队列中的消息
    messages = redis_client.lrange('celery', 0, -1)
    if not messages:
        print("Redis队列中没有消息")
        return None
    
    # 分析每个消息
    for i, message in enumerate(messages):
        print(f"\n消息 #{i+1}:")
        try:
            msg_data = json.loads(message)
            print("消息结构:")
            print(json.dumps(msg_data, indent=2, ensure_ascii=False))
            
            # 分析消息体
            body = msg_data.get('body')
            if body:
                try:
                    # 如果body是base64编码的，尝试解码
                    if isinstance(body, str):
                        try:
                            decoded_body = base64.b64decode(body).decode('utf-8')
                            body_json = json.loads(decoded_body)
                            print("\nBody内容 (解码后):")
                            print(json.dumps(body_json, indent=2, ensure_ascii=False))
                        except:
                            print("\nBody不是有效的base64或JSON")
                            print(f"原始Body: {body}")
                except Exception as e:
                    print(f"无法解析Body: {e}")
            
            # 分析headers
            headers = msg_data.get('headers')
            if headers:
                print("\nHeaders:")
                print(json.dumps(headers, indent=2, ensure_ascii=False))
            
            # 检查properties字段是否存在
            if 'properties' in msg_data:
                print("\nProperties字段存在")
            else:
                print("\n警告: Properties字段不存在 - 这可能是问题所在")
                
            return msg_data
                
        except Exception as e:
            print(f"无法解析消息: {e}")
            print(f"原始消息: {message}")
    
    return None

def analyze_python_message():
    """分析Python发送的Celery消息"""
    print("\n===== 分析Python发送的Celery消息 =====")
    
    # 清除现有消息
    clear_redis_celery_keys()
    
    # 发送Python任务
    task_id = send_python_task()
    
    # 捕获消息格式 - 需要快速捕获以免被worker消费
    time.sleep(0.5)  # 等待消息到达Redis
    message = capture_message_format()
    
    # 记录消息结构到文件
    if message:
        with open('python_message_format.json', 'w') as f:
            json.dump(message, f, indent=2, ensure_ascii=False)
        print(f"Python消息格式已保存到 python_message_format.json")
    
    # 等待任务完成
    time.sleep(2)
    
    # 检查任务结果
    result_key = f'celery-task-meta-{task_id}'
    if redis_client.exists(result_key):
        result_data = redis_client.get(result_key)
        try:
            result_json = json.loads(result_data)
            print(f"\n任务结果: {json.dumps(result_json, indent=2)}")
        except:
            print(f"\n任务结果 (原始): {result_data}")
    else:
        print(f"\n未找到任务 {task_id} 的结果")

def create_go_message_template():
    """基于Python消息创建Go消息模板"""
    print("\n===== 创建Go消息模板 =====")
    
    # 清除现有消息
    clear_redis_celery_keys()
    
    # 发送Python任务
    send_python_task()
    
    # 捕获消息格式
    time.sleep(0.5)
    message = capture_message_format()
    
    if message:
        # 创建Go消息模板
        print("\nGo客户端应该发送如下格式的消息:")
        print("-------------------------------")
        print("关键字段:")
        print("1. 确保消息中包含 'properties' 字段")
        
        if 'properties' in message:
            print(f"   properties示例: {json.dumps(message['properties'], indent=2)}")
        
        print("2. 确保headers中包含正确的任务信息")
        if 'headers' in message:
            print(f"   headers示例: {json.dumps(message['headers'], indent=2)}")
        
        print("-------------------------------")
        print("建议修改的Go代码部分:")
        print("""
        // 在创建任务消息时确保包含properties字段
        message := map[string]interface{}{
            "body": encodedBody,
            "headers": headers,
            "properties": map[string]interface{}{
                "correlation_id": taskID,
                "reply_to": "",
                "delivery_mode": 2,
                "delivery_info": map[string]interface{}{
                    "exchange": "",
                    "routing_key": "celery",
                },
                "priority": 0,
                "body_encoding": "base64",
                "delivery_tag": uuid.New().String(),
            },
        }
        """)

def main():
    print("===== Celery消息格式分析工具 =====")
    
    # 分析Python发送的消息
    analyze_python_message()
    
    # 创建Go消息模板
    create_go_message_template()
    
    print("\n分析完成。使用这些信息来修复Go客户端发送的消息格式。")

if __name__ == "__main__":
    main() 